﻿/*
	Clase Servidor la cual tiene incluido el código para enviar y recibir datos a travez del puerto serial,
	Este código fué probado en el laboratorio usando una conexión local con saldo a favor ya que envió perfectamente datos hacia la DSP y movió el podio
	con la notación de que posiblemente no hay retroalimentación, es decir no recibe datos de regreso en este caso ángulos.
	
	<<Probado exitosamente en el servidor (nodo S), conexion serial exitosa, envio adecuado hacia la 
	DSP, posterior movimiento del Podio de forma adecuada >>

**/

package ClientServeryCSerial;

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JLabel;
import java.awt.Font;
import java.awt.Color;
import javax.swing.JTextField;

/*.......Puerto Serial.....*/
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;

import org.lwjgl.input.*;
import javax.comm.*;
	

public class Server extends JFrame implements SerialPortEventListener{
	
	private JPanel contentPane;
	DataInputStream in;
	DataOutputStream out;
	private ServerSocket server;
	private Socket client;
	
	static JLabel entrada;
	private JTextField tF;
        
        /*.................................*/
        Thread readThread;

	public Server(){
		super("SERVIDOR ::.");
		configurarIU();
                abrirPuerto();

	}

	private void configurarIU() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 221, 172);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);		
		contentPane.setLayout(null);
		
		JButton btnSend = new JButton("Send");
		btnSend.setForeground(new Color(0, 128, 128));
		btnSend.addActionListener(new ActionListener() {
			
			/*****AL HACER CLICK ENVIAR MENSAJE AL CLIENTE***/
			public void actionPerformed(ActionEvent arg0) {
				
				 enviarDatos(tF.getText());
				//enviarDatos("I am Server");
				//mostrarMensaje("SERVER>>>...");
			}
		});
		btnSend.setBounds(157, 11, 38, 23);
		contentPane.add(btnSend);
		
		entrada = new JLabel("    SXXXE");
		entrada.setForeground(new Color(0, 128, 128));
		entrada.setFont(new Font("Tahoma", Font.BOLD, 26));
		entrada.setBounds(20, 71, 164, 52);
		contentPane.add(entrada);
		
		JLabel lblStringJoystic = new JLabel("String Joystic >>");
		lblStringJoystic.setForeground(new Color(0, 128, 128));
		lblStringJoystic.setFont(new Font("Tahoma", Font.BOLD, 16));
		lblStringJoystic.setBounds(20, 43, 146, 28);
		contentPane.add(lblStringJoystic);
		
		tF = new JTextField();
		tF.setForeground(new Color(0, 128, 128));
		tF.setFont(new Font("Tahoma", Font.BOLD, 13));
		tF.setBounds(10, 12, 137, 20);
		contentPane.add(tF);
		tF.setColumns(10);
	}
	
        /************************** ABRIMOS EL PUERTO 1000 ****************************/
    public void abrirPuerto(){
    	try {
			portId = CommPortIdentifier.getPortIdentifier(puerto);
		} catch (NoSuchPortException e) {}
		try {
			serialPort = (SerialPort)portId.open("SimpleReadApp", 1000);
		} catch (PortInUseException e) {}
        try {
                outp = serialPort.getOutputStream();
        } catch (IOException e) {}
		try {
			serialPort.setSerialPortParams(bps,
				SerialPort.DATABITS_8,
				SerialPort.STOPBITS_1,
				SerialPort.PARITY_NONE);
		} catch (UnsupportedCommOperationException e) {}
		try {
			inp = serialPort.getInputStream();
		} catch (IOException e) {}
		try {
			serialPort.addEventListener(this);
		} catch (TooManyListenersException e) {}
		try {
			serialPort.notifyOnDataAvailable(true);
			serialPort.enableReceiveTimeout(30);
		} catch (UnsupportedCommOperationException e) {}
                
                //Iniciar hilo encargado de esperar 
          /***
                readThread = new Thread(this);
                 readThread.start(); ***/
    }
    
     /***************************************************************************************************/    
/***	METODO QUE RECIBE UN STRING COMO PARAMETRO Y LUEGO LO ENVIA POR EL PUERTO SERIAL	***/
    public void enviar(String s){
		//messageAreaOut.append(s);
		try{
			outp.write(s.getBytes());
			System.out.print("El dato "+s+ " fue enviado correctamente! ");
			
		} catch (IOException e) {	System.out.println("Error!!! Fue imposible enviar el dato a!!!");}
	    try {
			Thread.currentThread().sleep(delay);
    	} catch (Exception e) {}
    }
    
    /**************************************************************************************************************/
	/***	METODO EMPLEADO PARA LEER LOS DATOS RECIBIDOS DE RETROALIMENTACI�N POR EL PUERTO SERIAL			**/
    public void serialEvent(SerialPortEvent event) {
        switch(event.getEventType()) {
        case SerialPortEvent.BI:
        case SerialPortEvent.OE:
        case SerialPortEvent.FE:
        case SerialPortEvent.PE:
        case SerialPortEvent.CD:
        case SerialPortEvent.CTS:
        case SerialPortEvent.DSR:
        case SerialPortEvent.RI:
        case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
            break;
        case SerialPortEvent.DATA_AVAILABLE:
            byte[] readBuffer = new byte[30];

            try {
                while (inp.available() > 0) {
                    int numBytes = inp.read(readBuffer);
                    for(int i=0; i<numBytes; i++){
                      	if(readBuffer[i]==(byte)83&&readBuffer[i+1]==(byte)115&&readBuffer[i+6]==(byte)69&&readBuffer[i+7]==(byte)115){
				for(int j=0; j<8; j++)
                                {       //Llenamos el array b[] con los datos recibidos de la DSP
					ib[j]=readBuffer[i+j];                                                                
		                    	//messageAreaIn.append((byte)ib[j]+",");
				}       
                                        //Mostramos los datos recibidos en el label correspondiente
         
                                //String datos = String.valueOf( (double)ib[2]*180/127);
                                enviarDatos(String.valueOf( (double)ib[2]*180/127));
                    /****
                    rot_sup.setText( String.valueOf( (double)ib[2]*180/127 ) );
                    inc_sup.setText( String.valueOf( (double)ib[3]*180/127 ) );
                    inc_med.setText( String.valueOf( (double)ib[4]*180/127 ) );
                    rot_cam.setText( String.valueOf( (double)ib[5]*180/127 ) );
					i=i+8;
                                 * ****/
                    	}else{
//                    		i=i+8;
                    	}
                    }
                }
            } catch (IOException e) {}
            break;
        }
    }
	
        public void ejecutarServer()
	{
		try {
			 // Paso 1: crear un objeto ServerSocket.
	         server = new ServerSocket( 12345, 100 );
	         
	
		while(true)
		{
		
		// conectarse al servidor, obtener flujos, procesar la conexi�n
	      try {
	    	 esperarConexion();// Paso 2: esperar una conexi�n.
	    	 configurarServer(); // Paso 3: crear un socket para realizar la conexi�n
	         procesarConexion(); // Paso 4: procesar la conexi�n
	      }

	      // el servidor cerr� la conexi�n
	      catch ( EOFException excepcionEOF ) {
	         System.err.println( "El cliente termino la conexi�n" );
	      }

	      // procesar los problemas que pueden ocurrir al comunicarse con el servidor
	      catch ( IOException excepcionES ) {
	         excepcionES.printStackTrace();
	      }

	      finally {
	        // cerrarConexion(); // Paso 4: cerrar la conexi�n
	      		}
		} 
		}catch (Exception e) {
			// TODO: handle exception
		}
	   } // fin del m�todo ejecutarCliente		
	/**
	 * @throws IOException ******************************************************************/
	
	private void esperarConexion() throws IOException {
	    mostrarMensaje( "Esperando una conexi�n\n" );
	      client = server.accept(); // permitir al servidor aceptar la conexi�n            
	      mostrarMensaje( "Conexi�n recibida de: " +
	         client.getInetAddress().getHostName() );
	  	}

	private void configurarServer() throws IOException {

		in = new DataInputStream(client.getInputStream());
		out = new DataOutputStream(client.getOutputStream());		
	}
	
	/******************************************************************************/
	/**********	RECIBIR LOS DATOS ENVIADOS POR EL CLIENTE	*********/
	private void procesarConexion() throws IOException
	   {	      
	      	String mensaje = "Conectado a "
                                            +client.getInetAddress().getHostName(); // enviar mensaje de conexi�n exitosa al cliente
	      	 			
	      			mostrarMensaje( mensaje );

	      		   do { // procesar los mensajes enviados por el cliente
                             
                               try{
                            	   mensaje = in.readUTF();
                                   entrada.setText("    "+mensaje);
                                   /*............. Enviar dato recibido a la DSP ..............*/
                                   enviar(mensaje);
                                   
                            	   mostrarMensaje( "CLIENT SAYS>>>" + mensaje );
                                    
                                }
                                  catch ( Exception e ) {
                                     mostrarMensaje( "\nSe recibió un tipo de objeto desconocido" );
                                 }


                               } while ( !mensaje.equals( "CLIENTE>>> TERMINAR" ) );
	   }
	/********************************************************************************/   
	
	   // cerrar flujos y socket
	   private void cerrarConexion() 
	   {
	      mostrarMensaje( "\nFinalizando la conexi�n\n" );
	      try {
	         out.close();
	         in.close();
	         client.close();
	      }
	      catch( IOException excepcionES ) {
	         excepcionES.printStackTrace();
	      }
	   }

	/***********************************************************************************/
	   /********	ENVIAR DATOS AL CLIENTE	*******/	
	public void enviarDatos( String mensaje )
	   {
		   		try {
		   			out.writeUTF(mensaje);
				} catch (Exception e) {
					System.out.println("Error al enviar el dato al Cliente");
				}
	   }	
	   
/***********************************************************************************/
	   /********	MOSTRAR TODOS LOS MENSAJES EN CONSOLA Y LUEGO EN JFORM	*******/
	   private void mostrarMensaje(String dato) {
			System.out.println(dato);
		
	}
/***********************************************************************************/	
	
/*************************[	MAIN ]******************************/
	public static void main(String[] args) {
		
	      JFrame.setDefaultLookAndFeelDecorated(true);
	      Server aplicacion = new Server();
	      aplicacion.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
	      aplicacion.setVisible(true);
	      aplicacion.ejecutarServer();

	}
        
        /*.............ATRIBUTOS...............*/
    //public boolean codif = true;
	
    final String puerto = "COM1";
    final int bps = 9600;
    final int muestra = 200;
    final int delay = 20;

    static CommPortIdentifier portId;
    static SerialPort serialPort;
    static OutputStream outp;
    static InputStream inp;
    static Enumeration portList;

    private TextArea messageAreaOut;
    private TextArea messageAreaIn;

    private byte[] b = new byte[60];
    private byte[] ib = new byte[60];
    private int n=0;
    //private String in = new String("");
    private String temp = new String();
    
    int d;
}
